package com.tjbank.cssys.service.impl;

import com.tjbank.cssys.api.PermissionService;
import com.tjbank.cssys.api.RelationIDService;
import com.tjbank.cssys.api.UserService;
import com.tjbank.cssys.dto.*;
import com.tjbank.cssys.framework.base.enums.YesOrNoEnum;
import com.tjbank.cssys.framework.base.exception.ServiceException;
import com.tjbank.cssys.framework.base.util.GeneratIDUtil;
import com.tjbank.cssys.mybatis.IamGroupDao;
import com.tjbank.cssys.mybatis.IamRelationshipDao;
import com.tjbank.cssys.mybatis.IamRoleDao;
import com.tjbank.cssys.mybatis.IamUserDao;
import com.tjbank.cssys.mybatis.*;
import com.tjbank.cssys.service.enums.LogTypeEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;



import com.tjbank.cssys.mybatis.entity.*;
import com.tjbank.cssys.mybatis.sqlbuilder.IamRelationshipSqlBuilder;
import com.tjbank.cssys.mybatis.sqlbuilder.IamUserSqlBuilder;
import com.tjbank.cssys.service.convert.PostConvert;
import com.tjbank.cssys.service.convert.RoleConvert;
import com.tjbank.cssys.service.convert.UserConvert;
import com.tjbank.cssys.service.enums.PermTypeEnum;
import com.tjbank.cssys.service.util.Const;
import com.tjbank.cssys.service.util.PermissionUtil;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 用户
 * 
 * Package : com.tansun.magicube.iam.service.impl
 * 
 * @author -- lijiangtao 2020年5月5日 下午6:01:03
 *
 */
@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private IamUserDao userDao;

	@Autowired
	private IamRelationshipDao relationshipDao;

	/** 关联关系ID **/
	@Autowired
	private RelationIDService relationIDService;

	/** 角色 **/
	@Autowired
	private IamRoleDao roleDao;

	/** 组 **/
	@Autowired
	private IamGroupDao groupDao;

	/** 新增关联关系 **/
	@Autowired
	private RelationAddServiceImpl relationAddService;

	@Autowired
	private PermissionService permissionService;

	@Autowired
	private IamLogDao logDao;

	/**
	 * 新增用户
	 * 
	 * @param userDTO
	 * @return
	 * @author -- lijiangtao 2020年5月9日 下午4:46:37
	 */
	@Override
	@Transactional
	public Integer addUser(UserDTO userDTO) {
		this.checkParam(userDTO);
		IamUser entity = UserConvert.INSTANCE.dtoToEntity(userDTO);
		entity.setId(GeneratIDUtil.getUUId());
		if (Objects.equals(userDTO.getIsEncryption(), YesOrNoEnum.NO.getCode())) {
			entity.setPassword(DigestUtils.md5DigestAsHex(entity.getPassword().getBytes()));
		}
		entity.setCreateTime(new Date());
		entity.setUpdateTime(new Date());
		entity.setState(YesOrNoEnum.YES.getCode());
		relationAddService.addURRelation(userDTO, entity);
		relationAddService.addUPRelationship(userDTO, entity);
		return userDao.insert(entity);
	}

	/**
	 * 根据租户Code分页查询用户信息
	 * 
	 * @param userDTO
	 * @param pageable
	 * @return
	 * @author -- lijiangtao 2020年7月25日 下午11:50:31
	 */
	@Override
	@SuppressWarnings("all")
	public Page<UserDTO> queryUserByTenantCode(UserDTO userDTO, Pageable pageable) {
		IamUserSqlBuilder sqlBuilder = setSqlBuilderByTenantCode(userDTO, pageable);
		return new PageImpl(UserConvert.INSTANCE.entitiesToDtoList(userDao.selectListBySqlBuilder(sqlBuilder)), pageable, userDao.countBySqlBuilder(sqlBuilder));
	}

	/**
	 * setSqlBuilderByTenantCode
	 * 
	 * @param userDTO
	 * @param pageable
	 * @author -- lijiangtao 2020年5月7日 下午2:17:41
	 */
	private IamUserSqlBuilder setSqlBuilderByTenantCode(UserDTO userDTO, Pageable pageable) {
		if (StringUtils.isBlank(userDTO.getTenantCode())) {
			throw new ServiceException("tenantCode:租户代码不能为空");
		}
		IamUserSqlBuilder sqlBuilder = new IamUserSqlBuilder();
		sqlBuilder.setPageSize(pageable.getPageSize());
		sqlBuilder.setIndexNo((int) pageable.getOffset());
		if (StringUtils.isNotBlank(userDTO.getUserCode())) {
			sqlBuilder.andUserCodeLikeBoth(userDTO.getUserCode());
		}
		if (StringUtils.isNotBlank(userDTO.getUserName())) {
			sqlBuilder.andUserNameLikeBoth(userDTO.getUserName());
		}
		sqlBuilder.andTenantCodeEqualTo(userDTO.getTenantCode()).andIsDeletedEqualTo(YesOrNoEnum.NO.getCode());
		sqlBuilder.orderByUpdateTime(true).setAutoFilterNull(true);
		return sqlBuilder;
	}

	/**
	 * 根据用户ID查询
	 * 
	 * @param userId
	 * @return
	 * @author -- lijiangtao 2020年6月19日 下午3:58:40
	 */
	@Override
	public UserDetailsDTO queryUserById(String userId) {
		this.checkUserId(userId);
		UserDetailsDTO userDetailsDTO = new UserDetailsDTO();
		userDetailsDTO.setUserDTO(this.getUserById(userId)).setPostList(this.queryPostByUserId(userId)).setRoleList(this.queryRoleListByUserId(userId));
		return userDetailsDTO;
	}

	/**
	 * 根据用户ID查询用户信息
	 * 
	 * @param userId
	 * @return
	 * @author -- lijiangtao 2020年6月20日 下午3:25:28
	 */
	private UserDTO getUserById(String userId) {
		return UserConvert.INSTANCE.entityToDto(userDao.selectByPrimaryKey(new IamUserKey(userId)));
	}

	/**
	 * 根据用户ID查询岗位信息
	 * 
	 * @param userId
	 * @return
	 * @author -- lijiangtao 2020年5月19日 下午3:13:27
	 */
	private List<PostDTO> queryPostByUserId(String userId) {
		List<IamGroup> groupList = new ArrayList<IamGroup>();
		relationIDService.queryPostIdByUserId(userId).forEach(id -> groupList.add(groupDao.selectByPrimaryKey(new IamGroupKey(id))));
		return PostConvert.INSTANCE.entitiesToDtoList(groupList);
	}

	/**
	 * 根据用户ID查询角色信息
	 * 
	 * @param userId
	 * @return
	 * @author -- lijiangtao 2020年5月9日 上午10:06:28
	 */
	@Override
	public List<RoleDTO> queryRoleListByUserId(String userId) {
		List<IamRole> roleList = new ArrayList<>();
		relationIDService.queryRoleIdListByUserId(userId).forEach(id -> roleList.add(roleDao.selectByPrimaryKey(new IamRoleKey(id))));
		return RoleConvert.INSTANCE.entitiesToDtoList(roleList);
	}

	/**
	 * 删除
	 * 
	 * @param userId
	 * @return
	 * @author -- lijiangtao 2020年5月9日 下午4:46:40
	 */
	@Override
	@Transactional
	public Integer deleteUser(String userId) {
		this.checkUserId(userId);
		this.deleteUXRelation(userId);
		this.deleteXURelation(userId);
		return userDao.deleteByPrimaryKey(new IamUserKey(userId));
	}

	/**
	 * 删除用户__XX关联关系
	 * 
	 * @param userId
	 * @author -- lijiangtao 2020年6月18日 下午8:39:23
	 */
	private void deleteUXRelation(String userId) {
		IamRelationshipSqlBuilder sqlBuilder = new IamRelationshipSqlBuilder();
		sqlBuilder.andEntity1CodeEqualTo(userId);
		relationshipDao.deleteBySqlBuilder(sqlBuilder);
	}

	/**
	 * 删除XX__用户关联关系
	 * 
	 * @param userId
	 * @author -- lijiangtao 2020年6月18日 下午8:40:14
	 */
	private void deleteXURelation(String userId) {
		IamRelationshipSqlBuilder sqlBuilder = new IamRelationshipSqlBuilder();
		sqlBuilder.andEntity2CodeEqualTo(userId);
		relationshipDao.deleteBySqlBuilder(sqlBuilder);
	}

	/**
	 * 更新
	 * 
	 * @param userDTO
	 * @return
	 * @author -- lijiangtao 2020年5月9日 下午4:46:42
	 */
	@Override
	@Transactional
	public Integer updateUser(UserDTO userDTO) {
		this.checkUserId(userDTO.getId());
		IamUser entity = UserConvert.INSTANCE.dtoToEntity(userDTO);
		entity.setUpdateTime(new Date());
		IamUserSqlBuilder sqlBuilder = new IamUserSqlBuilder();
		sqlBuilder.andIdEqualTo(entity.getId());
		relationAddService.deleteRoleByUserId(userDTO.getId());
		relationAddService.addURRelation(userDTO, entity);
		relationAddService.deleteUPRelationship(userDTO.getId());
		relationAddService.addUPRelationship(userDTO, entity);
		return userDao.updateBySqlBuilderSelective(entity, sqlBuilder);
	}

	/**
	 * 根据userCode获取用户信息
	 * 
	 * @param userCode
	 * @return
	 * @author -- lijiangtao 2020年6月11日 下午3:19:42
	 */
	@Override
	public UserDTO getUser(String tenantCode, String userCode) {
		IamUserSqlBuilder sqlBuilder = new IamUserSqlBuilder();
		sqlBuilder.andTenantCodeEqualTo(tenantCode).andUserCodeEqualTo(userCode).andIsDeletedEqualTo(YesOrNoEnum.NO.getCode());
		return UserConvert.INSTANCE.entityToDto(userDao.selectBySqlBuilder(sqlBuilder));
	}

	/**
	 * 用户登录成功,查询用户权限
	 * 
	 * 根据用户Code获取当前用户所能看到所有菜单
	 * 
	 * @param userCode
	 * @return
	 * @author -- lijiangtao 2020年6月13日 上午10:00:59
	 */
	@Override
	public PermDTO queryPermission(String tenantCode, String userCode) {
		PermDTO permDTO = new PermDTO();
		if (Objects.deepEquals(tenantCode, Const.ROOT_TENANT_CODE) && Objects.deepEquals(userCode, Const.ROOT_USER_CODE)) {
			permDTO.setMenuPerm(permissionService.permissionTreeList(new PermissionDTO(PermTypeEnum.MENU_PERM.getCode())));

//		    不删除  @author  -- lijiangtao  2020年7月31日 下午12:33:57
//			1.1版本增加数据权限
//			permDTO.setApiPerm(permissionService.permissionTreeList(new PermissionDTO(PermTypeEnum.API_PERM.getCode())));
			return permDTO;
		}
		UserDTO userDTO = this.getUser(tenantCode, userCode);
		List<RoleDTO> roleList = this.queryRoleListByUserId(userDTO.getId());
		if (roleList == null || roleList.isEmpty()) {
			throw new ServiceException("数据异常,此用户没有角色");
		}
		permDTO.setMenuPerm(PermissionUtil.listToTree(relationIDService.queryMenuPermByRoleId(roleList)));
		return permDTO;
	}

	/**
	 * 修改密码
	 * 
	 * 前端密码已做加密
	 * 
	 * @param userDTO
	 * @return
	 * @author -- lijiangtao 2020年7月17日 下午1:49:44
	 */
	@Override
	public Integer updatePassword(UserDTO userDTO) {
		IamUser user = userDao.selectByPrimaryKey(new IamUserKey(userDTO.getId()));
		if (!Objects.deepEquals(user.getPassword(), userDTO.getOldPassword())) {
			throw new ServiceException("原密码不正确!");
		}

		//记录密码修改日志
		IamLog iamLog = new IamLog();
		iamLog.setId(GeneratIDUtil.getUUId());
		iamLog.setLogTime(new Date());
		iamLog.setLogUser(userDTO.getId());
		iamLog.setLogType(LogTypeEnum.UPDATE_PWD_TYPE.getCode());//2为修改密码
		iamLog.setLogNote(" "+userDTO.getUserName()+"  updatePassword , success !");
		logDao.insert(iamLog);
		return userDao.updateByPrimaryKeySelective(UserConvert.INSTANCE.dtoToEntity(userDTO));
	}

	/**
	 * 根据机构ID查询用户信息
	 * 
	 * @param organId
	 * @return
	 * @author -- lijiangtao 2020年7月14日 下午4:07:18
	 */
	@Override
	public List<UserDTO> queryUserByOrganId(String organId) {
		IamUserSqlBuilder sqlBuilder = new IamUserSqlBuilder();
		sqlBuilder.andOrganIdEqualTo(organId).andIsDeletedEqualTo(YesOrNoEnum.NO.getCode());
		return UserConvert.INSTANCE.entitiesToDtoList(userDao.selectListBySqlBuilder(sqlBuilder));
	}

	/**
	 * 校验用户ID
	 * 
	 * @param userId
	 * @author -- lijiangtao 2020年6月17日 下午8:30:20
	 */
	private void checkUserId(String userId) {
		if (StringUtils.isBlank(userId)) {
			throw new ServiceException("用户ID不能为空");
		}
	}

	/**
	 * 参数校验
	 * 
	 * @param userDTO
	 * @author -- lijiangtao 2020年6月18日 下午7:46:52
	 */
	private void checkParam(UserDTO userDTO) {
		IamUserSqlBuilder sqlBuilder = new IamUserSqlBuilder();
		sqlBuilder.andTenantCodeEqualTo(userDTO.getTenantCode()).andUserCodeEqualTo(userDTO.getUserCode());
		if (!Objects.isNull(userDao.selectBySqlBuilder(sqlBuilder))) {
			throw new ServiceException("用户代码已存在");
		}
	}
}
